package com.lcxw.hxzbapi.controller.paycontroller;

import com.alibaba.fastjson.JSON;
import com.lcxw.hxzbapi.entity.pojo.VipBuyDetail;
import com.lcxw.hxzbapi.entity.pojo.YwpdChargeDetail;
import com.lcxw.hxzbapi.entity.requestBean.GetVipBuyOrderInfoReqWepay;
import com.lcxw.hxzbapi.entity.requestBean.GetWePayOrderReq;
import com.lcxw.hxzbapi.entity.response.Response;
import com.lcxw.hxzbapi.entity.response.WxPayOrderResp;
import com.lcxw.hxzbapi.service.VipBuyDetailService;
import com.lcxw.hxzbapi.service.YwpdChargeDetailService;
import com.lcxw.hxzbapi.service.YwpdMemberService;
import com.lcxw.hxzbapi.tencentim.common.ImCommand;
import com.lcxw.hxzbapi.tencentim.common.TencentImRealization;
import com.lcxw.hxzbcommon.common.StringUtil;
import com.lcxw.hxzbcommon.entity.ErrorCode;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import org.jdom.JDOMException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
@Slf4j
public class WxPayRealization {

    @Resource
    YwpdChargeDetailService ywpdChargeDetailService;

    @Resource
    YwpdMemberService ywpdMemberService;

    @Resource
    VipBuyDetailService vipBuyDetailService;

    @Autowired
    private TencentImRealization tencentImRealization;


    public Response getWePayOrderInfo(GetWePayOrderReq getWePayOrderReq, String remoteAddr) {

        String userId = getWePayOrderReq.getUserId();
        String body = getWePayOrderReq.getBody();
        double rmbDouble = getWePayOrderReq.getRmb();
        int rmb = (int) (rmbDouble * 100);

        int ratio = getWePayOrderReq.getRatio();
        int coin = getWePayOrderReq.getCoin();

        //这里生成唯一的订单id
        String outTradeNo = StringUtil.getOrderIdByUUId(1);

        //生成随机字符串
        String nonce_str = WxPayUtils.getRandomString(32);

        SortedMap<String, Object> parameters = new TreeMap<>();
        parameters.put("appid", WxPayConfig.APPID);
        parameters.put("mch_id", WxPayConfig.MCH_ID);
        parameters.put("nonce_str", nonce_str);
        parameters.put("body", body);
        parameters.put("out_trade_no", outTradeNo);
        parameters.put("total_fee", rmb);
        parameters.put("spbill_create_ip", remoteAddr);
        parameters.put("notify_url", WxPayConfig.WXPAY_NOTIFY_URL);
        parameters.put("trade_type", "APP");

        String sign = WxPayUtils.createSign(parameters);

        parameters.put("sign", sign);

        String requestXml = WxPayUtils.getRequestXml(parameters);

        RequestBody requestBody = RequestBody
            .create(MediaType.parse("application/xml"), requestXml);
        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder()
            .url(WxPayConfig.urlWx)
            .post(requestBody)
            .build();
        okhttp3.Response response;
        try {
            response = client.newCall(request).execute();
        } catch (IOException e) {
            return Response.error(ErrorCode.EXTERNAL_ERROR, "向微信平台发送预支付订单失败");
        }
        log.info("向微信平台发送预支付订单结果：" + response.toString());
        Map prepayMap = null;
        try {
            prepayMap = WxPayUtils.doXMLParse(response.body().string());
        } catch (Exception e) {
            e.printStackTrace();
            log.error("解析微信平台响应失败");
        }

        if (!(prepayMap.get("return_code")).equals("SUCCESS")) {
            log.error(prepayMap.toString());
            return Response.error(ErrorCode.EXTERNAL_ERROR, prepayMap.get("return_msg").toString());
        }
        if (!(prepayMap.get("result_code")).equals("SUCCESS")) {
            return Response
                .error(ErrorCode.EXTERNAL_ERROR, prepayMap.get("err_code_des").toString());
        }
        String prepay_id = prepayMap.get("prepay_id").toString();

        //开始生成一条充值记录，插入到数据库中
        YwpdChargeDetail ywpdChargedetail = new YwpdChargeDetail();
        ywpdChargedetail.setUserId(Long.parseLong(userId));
        ywpdChargedetail.setOrderNo(outTradeNo);//我们的orderNo对应支付宝的outTradeNo
        ywpdChargedetail.setChargeMode("微信");
        ywpdChargedetail.setRmb((float) rmbDouble);
        ywpdChargedetail.setCoin(coin);
        ywpdChargedetail.setContent(body);
        ywpdChargedetail.setStatus("创建交易");
        ywpdChargedetail.setProxyUId(null);
        ywpdChargedetail.setDealId(null);
        ywpdChargeDetailService.addChargeDetail(ywpdChargedetail);

        log.info("用户申请交易，创建交易记录：{}", ywpdChargedetail.toString());

        WxPayOrderResp wxPayOrderResp = new WxPayOrderResp();
        wxPayOrderResp.setAppid(WxPayConfig.APPID);
        wxPayOrderResp.setPartnerid(WxPayConfig.MCH_ID);
        wxPayOrderResp.setPrepayid(prepay_id);

        wxPayOrderResp.setNoncestr(nonce_str);
        String timestamp = WxPayUtils.getSecondTimestamp();
        wxPayOrderResp.setTimestamp(timestamp);

        SortedMap<String, Object> responseMap = new TreeMap<>();
        responseMap.put("appid", WxPayConfig.APPID);
        responseMap.put("partnerid", WxPayConfig.MCH_ID);
        responseMap.put("prepayid", prepay_id);
        responseMap.put("package", "Sign=WXPay");
        responseMap.put("noncestr", nonce_str);
        responseMap.put("timestamp", timestamp);
        String resultSign = WxPayUtils.createSign(responseMap);

        wxPayOrderResp.setSign(resultSign);

        return Response.ok(wxPayOrderResp);
    }

    public void dealWxpayCallback(HttpServletRequest request, HttpServletResponse response)
        throws IOException, JDOMException {
        BufferedReader in = new BufferedReader(new InputStreamReader(request.getInputStream()));
        StringBuilder stb = new StringBuilder();
        String line = null;
        while ((line = in.readLine()) != null) {
            stb.append(line);
        }
        Map map = WxPayUtils.doXMLParse(stb.toString());
        String return_code = (String) map.get("return_code");
        String return_msg = (String) map.get("return_msg");
        String result_code = (String) map.get("result_code");
        String thirdOrderNo = (String) map.get("transaction_id");
        String orderNo = (String) map.get("out_trade_no");
        String chargeTime = (String) map.get("time_end");
        String thirdBuyerAccount = (String) map.get("openid");
        String thirdSellerAccount = (String) map.get("mch_id");

        if (return_code.equals("SUCCESS") && result_code.equals("SUCCESS")) {
            YwpdChargeDetail ywpdChargedetail = ywpdChargeDetailService.selectByOrderNo(orderNo);
            ywpdChargedetail.setThirdOrderNo(thirdOrderNo);
            ywpdChargedetail.setChargeTime(chargeTime);
            ywpdChargedetail.setThirdBuyerAccount(thirdBuyerAccount);
            ywpdChargedetail.setThirdSellerAccount(thirdSellerAccount);
            ywpdChargedetail.setThirdBuyerEmail(null);
            ywpdChargedetail.setThirdSellerEmail(null);
            ywpdChargedetail.setStatus("交易成功");
            ywpdChargeDetailService.updateStatusByOrderNo(ywpdChargedetail);

            //完成支付后，将用户充进的虚拟货币添加到用户数据中
            ywpdMemberService
                .updateCoinByUserId(ywpdChargedetail.getCoin(), ywpdChargedetail.getUserId());
            if(null!=ywpdChargedetail&&!ywpdChargedetail.getContent().contains("VIP")){
                Response msg = new Response();
                msg.setCode(ImCommand.RECHARGE_NOTICE);
                msg.setDesc("Hi,你已成功充值"+ywpdChargedetail.getCoin()+"幸运币,可以用来购买会员和礼物。");
                tencentImRealization.sendmsg(tencentImRealization.generateUserBody(JSON.toJSONString(msg),ywpdChargedetail.getUserId()+""));
            }
            vipBuyDetailService.checkVipBuyDetail(orderNo);
        }

        TreeMap<String, Object> responseMap = new TreeMap<>();
        responseMap.put("return_code", "SUCCESS");
        String requestXml = WxPayUtils.getRequestXml(responseMap);
        PrintWriter writer = response.getWriter();
        writer.print(requestXml);
        writer.flush();
        writer.close();
    }

    //获取微信购买vip订单详情的方法
    public Response getVipOrderInfo(GetVipBuyOrderInfoReqWepay getVipBuyOrderInfoReqWepay,
        String remoteAddr) {

        String userId = getVipBuyOrderInfoReqWepay.getUserId();
        String body = getVipBuyOrderInfoReqWepay.getBody();
        String vipType = getVipBuyOrderInfoReqWepay.getVipType();
        double rmbDouble = getVipBuyOrderInfoReqWepay.getRmb();
        int rmb = (int) (rmbDouble * 100);

        //这里生成唯一的订单id
        String outTradeNo = StringUtil.getOrderIdByUUId(1);

        //生成随机字符串
        String nonce_str = WxPayUtils.getRandomString(32);

        SortedMap<String, Object> parameters = new TreeMap<>();
        parameters.put("appid", WxPayConfig.APPID);
        parameters.put("mch_id", WxPayConfig.MCH_ID);
        parameters.put("nonce_str", nonce_str);
        parameters.put("body", body);
        parameters.put("out_trade_no", outTradeNo);
        parameters.put("total_fee", rmb);
        parameters.put("spbill_create_ip", remoteAddr);
        parameters.put("notify_url", WxPayConfig.WXPAY_NOTIFY_URL);
        parameters.put("trade_type", "APP");

        String sign = WxPayUtils.createSign(parameters);

        parameters.put("sign", sign);

        String requestXml = WxPayUtils.getRequestXml(parameters);

        RequestBody requestBody = RequestBody
            .create(MediaType.parse("application/xml"), requestXml);
        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder()
            .url(WxPayConfig.urlWx)
            .post(requestBody)
            .build();
        okhttp3.Response response;
        try {
            response = client.newCall(request).execute();
        } catch (IOException e) {
            return Response.error(ErrorCode.EXTERNAL_ERROR, "向微信平台发送预支付订单失败");
        }
        log.info("向微信平台发送预支付订单结果：" + response.toString());
        Map prepayMap = null;
        try {
            prepayMap = WxPayUtils.doXMLParse(response.body().string());
        } catch (Exception e) {
            e.printStackTrace();
            log.error("解析微信平台响应失败");
        }

        if (!(prepayMap.get("return_code")).equals("SUCCESS")) {
            log.error(prepayMap.toString());
            return Response.error(ErrorCode.EXTERNAL_ERROR, prepayMap.get("return_msg").toString());
        }
        if (!(prepayMap.get("result_code")).equals("SUCCESS")) {
            return Response
                .error(ErrorCode.EXTERNAL_ERROR, prepayMap.get("err_code_des").toString());
        }
        String prepay_id = prepayMap.get("prepay_id").toString();

        //开始生成一条充值记录，插入到数据库中
        YwpdChargeDetail ywpdChargedetail = new YwpdChargeDetail();
        ywpdChargedetail.setUserId(Long.parseLong(userId));
        ywpdChargedetail.setOrderNo(outTradeNo);//我们的orderNo对应支付宝的outTradeNo
        ywpdChargedetail.setChargeMode("微信");
        ywpdChargedetail.setRmb((float) rmbDouble);
        ywpdChargedetail.setCoin(0);
        ywpdChargedetail.setContent(body);
        ywpdChargedetail.setStatus("创建交易");
        ywpdChargedetail.setProxyUId(null);
        ywpdChargedetail.setDealId(null);
        ywpdChargeDetailService.addChargeDetail(ywpdChargedetail);

        log.info("用户申请交易，创建交易记录：{}", ywpdChargedetail.toString());

        //vip的购买记录，插入到数据库
        VipBuyDetail vipBuyDetail = new VipBuyDetail();
        vipBuyDetail.setOrderNo(outTradeNo);
        vipBuyDetail.setUserId(Long.parseLong(userId));
        vipBuyDetail.setVipType(vipType);
        vipBuyDetail.setAddTime(StringUtil.getDateTime());
        vipBuyDetail.setStatus("0");
        vipBuyDetailService.save(vipBuyDetail);

        WxPayOrderResp wxPayOrderResp = new WxPayOrderResp();
        wxPayOrderResp.setAppid(WxPayConfig.APPID);
        wxPayOrderResp.setPartnerid(WxPayConfig.MCH_ID);
        wxPayOrderResp.setPrepayid(prepay_id);

        wxPayOrderResp.setNoncestr(nonce_str);
        String timestamp = WxPayUtils.getSecondTimestamp();
        wxPayOrderResp.setTimestamp(timestamp);

        SortedMap<String, Object> responseMap = new TreeMap<>();
        responseMap.put("appid", WxPayConfig.APPID);
        responseMap.put("partnerid", WxPayConfig.MCH_ID);
        responseMap.put("prepayid", prepay_id);
        responseMap.put("package", "Sign=WXPay");
        responseMap.put("noncestr", nonce_str);
        responseMap.put("timestamp", timestamp);
        String resultSign = WxPayUtils.createSign(responseMap);

        wxPayOrderResp.setSign(resultSign);

        return Response.ok(wxPayOrderResp);

    }
}
